"""
Author: ZhengShiQi
DateTime: 2025/9/11 15:00
FileName: app_launcher.py
Description: 用于启动FastWire-APIMock应用程序的类
"""

import os
import subprocess
import sys
from pathlib import Path

# 添加项目根目录到Python路径
sys.path.append(str(Path(__file__).parent.parent))

# 导入加载mock配置的函数
from scripts.load_mocks_to_wiremock import load_mocks_to_wiremock


class AppLauncher:
    """用于启动FastWire-APIMock应用程序的类"""
    
    def __init__(self, project_root: str = None):
        """初始化AppLauncher
        
        Args:
            project_root (str, optional): 项目根目录路径. 如果未提供，则使用当前工作目录.
        """
        self.project_root = Path(project_root) if project_root else Path.cwd()
        self.wiremock_path = self.project_root / "wiremock" / "wiremock-standalone.jar"
    
    def start_wiremock(self, port: int = 8080, bind_address: str = "0.0.0.0"):
        """启动WireMock服务
        
        Args:
            port (int, optional): WireMock服务端口. 默认为8080.
            bind_address (str, optional): WireMock绑定地址. 默认为"0.0.0.0".
        
        Returns:
            subprocess.Popen: WireMock服务进程对象
        """
        if not self.wiremock_path.exists():
            raise FileNotFoundError(f"WireMock JAR文件未找到: {self.wiremock_path}")
        
        cmd = [
            "java", "-jar", str(self.wiremock_path),
            "--port", str(port),
            "--bind-address", bind_address,
            "--verbose"
        ]
        
        print(f"启动WireMock服务在 {bind_address}:{port}...")
        return subprocess.Popen(cmd, cwd=self.project_root / "wiremock")
    
    def start_fastapi(self, host: str = "127.0.0.1", port: int = 8000):
        """启动FastAPI应用
        
        Args:
            host (str, optional): FastAPI应用主机地址. 默认为"127.0.0.1".
            port (int, optional): FastAPI应用端口. 默认为8000.
        """
        # 更改当前工作目录到项目根目录
        os.chdir(self.project_root)
        
        # 构建启动命令
        cmd = [
            sys.executable, "-m", "uvicorn", 
            "app.main:app",
            "--host", host,
            "--port", str(port),
            "--reload"
        ]
        
        print(f"启动FastAPI应用在 {host}:{port}...")
        subprocess.run(cmd)
    
    def start_all(self, fastapi_host: str = "127.0.0.1", fastapi_port: int = 8000, 
                  wiremock_port: int = 8080, wiremock_bind_address: str = "0.0.0.0"):
        """同时启动WireMock服务和FastAPI应用
        
        Args:
            fastapi_host (str, optional): FastAPI应用主机地址. 默认为"127.0.0.1".
            fastapi_port (int, optional): FastAPI应用端口. 默认为8000.
            wiremock_port (int, optional): WireMock服务端口. 默认为8080.
            wiremock_bind_address (str, optional): WireMock绑定地址. 默认为"0.0.0.0".
        """
        # 启动WireMock服务
        wiremock_process = self.start_wiremock(wiremock_port, wiremock_bind_address)
        
        # 等待WireMock服务启动完成
        import time
        time.sleep(5)
        
        # 从数据库加载Mock配置到WireMock
        try:
            load_mocks_to_wiremock()
            print("已从数据库加载Mock配置到WireMock")
        except Exception as e:
            print(f"加载Mock配置时出错: {str(e)}")
        
        try:
            # 启动FastAPI应用
            self.start_fastapi(fastapi_host, fastapi_port)
        finally:
            # 确保在退出时终止WireMock服务
            wiremock_process.terminate()
            wiremock_process.wait()
            print("WireMock服务已终止")


def main():
    """主函数，用于从命令行启动应用程序"""
    launcher = AppLauncher()
    
    # 可以通过命令行参数指定端口和绑定地址
    import argparse
    parser = argparse.ArgumentParser(description='启动FastWire-APIMock应用程序')
    parser.add_argument('--fastapi-host', default='127.0.0.1', help='FastAPI应用主机地址')
    parser.add_argument('--fastapi-port', type=int, default=8000, help='FastAPI应用端口')
    parser.add_argument('--wiremock-port', type=int, default=8080, help='WireMock服务端口')
    parser.add_argument('--wiremock-bind-address', default='0.0.0.0', help='WireMock绑定地址')
    
    args = parser.parse_args()
    
    launcher.start_all(
        fastapi_host=args.fastapi_host,
        fastapi_port=args.fastapi_port,
        wiremock_port=args.wiremock_port,
        wiremock_bind_address=args.wiremock_bind_address
    )

# python scripts/app_launcher.py --fastapi-port 8000 --wiremock-port 8080
if __name__ == "__main__":
    main()